/**
 * Copyright (C) 2017 - 2020 https://github.com/joewee
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.bifrost.aop;

import com.bifrost.entity.SystemLog;
import com.bifrost.exception.UnAuthorizationException;
import com.bifrost.repository.SystemLogRepository;
import com.bifrost.util.HttpContextUtils;
import com.bifrost.util.IPUtils;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.SignatureException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * 系统日志，切面处理类
 *
 * @author joewee
 * @version 1.0.0
 * @Date 2017/10/21 20:27
 */
//@Aspect
//@Component
public class SysErrorLogAspect {

    @Autowired
    SystemLogRepository systemLogRepository;

    @Pointcut("execution(* com.bifrost.service..*.*(..))")
    public void errLogPointCut() {
    }

    //仅记录500错误日志
    @AfterThrowing(value = "errLogPointCut()", argNames = "e", throwing = "e")
    public void saveSysErrLog(JoinPoint joinPoint, Exception e) {
        if (e instanceof UnAuthorizationException || e instanceof SignatureException ||
                e instanceof ExpiredJwtException) {
            return;
        }
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SystemLog sysLog = new SystemLog();
        //请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLog.setMethod(className + "." + methodName + "()");
        //请求的参数
        Object[] args = joinPoint.getArgs();
        if (args != null && args.length >= 1) {
            StringBuilder params = new StringBuilder();
            for (int i = 0; i < args.length; i++) {
                if (i == args.length - 1) {
                    params.append(args.getClass().getName());
                } else {
                    params.append(args.getClass().getName());
                    params.append(",");
                }
            }
            sysLog.setParams(params.toString());
        }
        //获取request
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        if (request != null) {
            //设置IP地址
            sysLog.setIp(IPUtils.getIpAddr(request));
            sysLog.setCreateDate(new Date());
            //会员Id
            Long customerId = null;
            Cookie[] cookies = request.getCookies();
            if (cookies != null && cookies.length >= 1) {
                for (Cookie cookie : cookies) {
                    if ("customerId".equals(cookie.getName())) {
                        customerId = Long.valueOf(cookie.getValue());
                    }
                }
            }
            sysLog.setCustomerId(customerId);
        }
        //异常信息
        StackTraceElement[] elements = e.getStackTrace();
        if (elements != null && elements.length >= 1) {
            StackTraceElement element = elements[elements.length - 1];
            sysLog.setErrFile(element.getFileName());
            sysLog.setErrLine(String.valueOf(element.getLineNumber()));
            systemLogRepository.save(sysLog);
        }
    }
}
